package top.xzxsrq.common.utils;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import top.xzxsrq.common.exception.BizException;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * @program: MyUtils
 * @create: 2021-09-22 13:05
 **/
public abstract class TimeUiltsZX extends DateUtils {
    /***
     * 日期时间格式
     */
    public static final String FORMAT_DATE_y2M = "yyMM";
    public static final String FORMAT_DATE_y2Md = "yyMMdd";
    public static final String FORMAT_DATE_y4 = "yyyy";
    public static final String FORMAT_DATE_y4Md = "yyyyMMdd";
    public static final String FORMAT_DATE_Y4MD = "yyyy-MM-dd";
    public static final String FORMAT_TIMESTAMP = "yyMMddhhmmss";
    public static final String FORMAT_TIME_HHmm = "HH:mm";
    public static final String FORMAT_TIME_HHmmss = "HH:mm:ss";
    public static final String FORMAT_DATETIME_Y4MDHM = "yyyy-MM-dd HH:mm";
    public static final String FORMAT_DATETIME_Y4MDHMS = "yyyy-MM-dd HH:mm:ss";
    /***
     * 星期
     */
    public static final String[] WEEK = new String[]{"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};


    /***
     * 当前的日期时间
     * @return format指定格式的日期时间
     */
    public static String now(String format) {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(cal.getTime());
    }

    /**
     * 当前日期时间串
     *
     * @return yyMMddhhmmss
     */
    public static String toTimestamp(Date date) {
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_TIMESTAMP);
        return sdf.format(date.getTime());
    }

    /**
     * 获取月份
     *
     * @return
     */
    public static String getMonth() {
        return now(FORMAT_DATE_y2M);
    }

    /***
     * 获取今天的日期
     * @return yyyyMMdd
     */
    public static String today() {
        return now(FORMAT_DATE_y4Md);
    }

    /***
     * 转换字符串为日期date
     * @param datetime
     * @param fmt
     * @return
     */
    public static Date convert2FormatDate(String datetime, String fmt) {
        if (StringUtils.isBlank(datetime)) {
            return null;
        }
        SimpleDateFormat format = new SimpleDateFormat(fmt);
        try {
            return format.parse(datetime);
        } catch (ParseException e) {
            System.out.println("日期格式转换异常");
        }
        return null;
    }

    /***
     * 转换date为格式化字符串
     * @param date
     * @param fmt
     * @return
     */
    public static String convert2FormatString(Date date, String fmt) {
        if (date == null) {
            return null;
        } else {
            SimpleDateFormat format = new SimpleDateFormat(fmt);
            return format.format(date);
        }
    }

    /**
     * 获取格式化的日期
     *
     * @param date       基准日期
     * @param daysOffset 偏移量
     * @return yyyy-MM-dd
     */
    public static String getDate(Date date, int... daysOffset) {
        if (date == null) {
            date = new Date();
        }
        if (daysOffset != null && daysOffset.length > 0) {
            date = addDays(date, daysOffset[0]);
        }
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATE_Y4MD);
        return sdf.format(date);
    }

    /**
     * 获取日期的下一天
     *
     * @param date 基准日期
     * @return yyyy-MM-dd
     */
    public static Date nextDay(Date date) {
        if (date == null) {
            return null;
        }
        return addDays(date, 1);
    }

    /***
     * 获取格式化的日期时间
     * @param date
     * @return yyyy-MM-dd HH:mm
     */
    public static String getDateTime(Date date, int... daysOffset) {
        if (date == null) {
            date = new Date();
        }
        if (daysOffset != null && daysOffset.length > 0) {
            date = addDays(date, daysOffset[0]);
        }
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATETIME_Y4MDHM);
        return sdf.format(date);
    }

    /**
     * 是否是工作时间段，用于后台程序等
     *
     * @return
     */
    public static boolean isWorkingTime() {
        Calendar cal = Calendar.getInstance();
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        return (hour >= 8 && hour < 20);
    }

    /***
     * 获取上午/下午
     * @return
     */
    public static String getAmPm() {
        Calendar c = Calendar.getInstance();
        int hours = c.get(Calendar.HOUR_OF_DAY);
        if (hours <= 9) {
            return "早上";
        } else if (hours <= 12) {
            return "上午";
        } else if (hours == 13) {
            return "中午";
        } else if (hours <= 18) {
            return "下午";
        } else {
            return "晚上";
        }
    }

    /**
     * 得到当前的年月YYMM，用于生成文件夹名称
     *
     * @return
     */
    public static String getYearMonth() {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATE_y2M);
        return sdf.format(cal.getTime());
    }

    /**
     * 得到当前的年月YYMM，用于生成文件夹
     *
     * @return
     */
    public static String getYearMonthDay() {
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat(FORMAT_DATE_y2Md);
        return sdf.format(cal.getTime());
    }

    /**
     * 得到当前的年月YYMM，用于生成文件夹
     *
     * @return
     */
    public static int getDay() {
        Calendar cal = Calendar.getInstance();
        return cal.get(Calendar.DAY_OF_MONTH);
    }

    /***
     * 获取日期对应的星期
     * @param date
     * @return
     */
    public static String getWeek(Date date) {
        return WEEK[Calendar.getInstance().get(Calendar.DAY_OF_WEEK)];
    }

    /**
     * 毫秒数转date
     *
     * @param timeMillis
     * @return
     */
    public static Date timeMillis2Date(Long timeMillis) {
        return new Date(timeMillis);
    }

    /**
     * 字符串时间戳转日期
     *
     * @param value
     * @return
     */
    public static Date datetimeString2Date(String value) {
        return convert2DateTime(value, FORMAT_DATETIME_Y4MDHMS);
    }

    /**
     * 字符串时间戳转日期
     *
     * @return
     */
    public static Date convert2Date(String date) {
        return convert2FormatDate(date, FORMAT_DATE_Y4MD);
    }

    /**
     * 字符串时间戳转日期
     *
     * @param dateTime
     * @return
     */
    public static Date convert2DateTime(String dateTime, String... dateFormat) {
        String f = FORMAT_DATETIME_Y4MDHM;
        if (dateFormat != null && dateFormat.length > 0) {
            f = dateFormat[0];
        }
        return convert2FormatDate(dateTime, f);
    }

    public static int getMonth(Date month) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(month);
        return cal.get(Calendar.MONTH) + 1;
    }

    public static int getYear(Date year) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(year);
        return cal.get(Calendar.YEAR);
    }

    public static List<String> getMonthList(String beginTime, String endTime) {
        List<String> result = new LinkedList<>();
        if (StringUtils.isEmpty(beginTime) || StringUtils.isEmpty(endTime)) {
            throw new BizException("月份开始时间或者结束时间不能为空");
        }
        if (beginTime.equals(endTime)) {
            result.add(beginTime);
            return result;
        }
        Date beginDate = TimeUiltsZX.convert2Date(beginTime);
        Date endDate = TimeUiltsZX.convert2Date(endTime);
        return TimeUiltsZX.getMonthList(beginDate, endDate);
    }


    public static List<String> getMonthList(Date beginDate, Date endDate) {
        List<String> result = new LinkedList<>();
        if (beginDate.after(endDate)) {
            throw new BizException("时间传入的结束时间不能在开始时间之前");
        }
        int beginYear = TimeUiltsZX.getYear(beginDate);
        int beginMonth = TimeUiltsZX.getMonth(beginDate);
        int endYear = TimeUiltsZX.getYear(endDate);
        int endMonth = TimeUiltsZX.getMonth(endDate);
        for (int i = beginYear; i <= endYear; i++) {
            for (int j = (i == beginYear ? beginMonth : 1); j <= (i == endYear ? endMonth : 12); j++) {
                result.add(i + "-" + NumberUtilsZX.doHandleZero(j, 2));
            }
        }
        return result;
    }


    public static int getDayOfMonth(Date month) {
        int year = TimeUiltsZX.getYear(month);
        int month1 = TimeUiltsZX.getMonth(month);
        switch (month1) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                return 31;
            case 4:
            case 6:
            case 9:
            case 11:
                return 30;
            case 2:
                return TimeUiltsZX.isLeapYear(year) ? 29 : 28;
        }
        return -1; // 表示错误
    }

    public static boolean isLeapYear(Date date) {
        return TimeUiltsZX.isLeapYear(TimeUiltsZX.getYear(date));
    }

    public static boolean isLeapYear(int year) {
        return year % 4 == 0 && year % 100 != 0 || year % 400 == 0;
    }

    //  System.out.println("一周的第几天: " + dow);  // 星期日 为一周的第一天输出为 1，星期一输出为 2，以此类推
    public static int getWeek(String day) {
        Date date = TimeUiltsZX.convert2Date(day);
        return TimeUiltsZX.getWeekInt(date);
    }

    /**
     * @param day
     * @return
     */
    public static int getWeekInt(Date day) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(day);
        return cal.get(Calendar.DAY_OF_WEEK);
    }
}
